package com.sheng.leetcode.year2023.month03.day13;

import org.junit.Test;

/**
 * @author liusheng
 * @date 2023/03/13
 * <p>
 * 2383. 赢得比赛需要的最少训练时长<p>
 * <p>
 * 你正在参加一场比赛，给你两个 正 整数 initialEnergy 和 initialExperience 分别表示你的初始精力和初始经验。<p>
 * 另给你两个下标从 0 开始的整数数组 energy 和 experience，长度均为 n 。<p>
 * 你将会 依次 对上 n 个对手。第 i 个对手的精力和经验分别用 energy[i] 和 experience[i] 表示。当你对上对手时，<p>
 * 需要在经验和精力上都 严格 超过对手才能击败他们，然后在可能的情况下继续对上下一个对手。<p>
 * 击败第 i 个对手会使你的经验 增加 experience[i]，但会将你的精力 减少  energy[i] 。<p>
 * 在开始比赛前，你可以训练几个小时。每训练一个小时，你可以选择将增加经验增加 1 或者 将精力增加 1 。<p>
 * 返回击败全部 n 个对手需要训练的 最少 小时数目。<p>
 * <p>
 * 示例 1：<p>
 * 输入：initialEnergy = 5, initialExperience = 3, energy = [1,4,3,2], experience = [2,6,3,1]<p>
 * 输出：8<p>
 * 解释：在 6 小时训练后，你可以将精力提高到 11 ，并且再训练 2 个小时将经验提高到 5 。<p>
 * 按以下顺序与对手比赛：<p>
 * - 你的精力与经验都超过第 0 个对手，所以获胜。<p>
 * 精力变为：11 - 1 = 10 ，经验变为：5 + 2 = 7 。<p>
 * - 你的精力与经验都超过第 1 个对手，所以获胜。<p>
 * 精力变为：10 - 4 = 6 ，经验变为：7 + 6 = 13 。<p>
 * - 你的精力与经验都超过第 2 个对手，所以获胜。<p>
 * 精力变为：6 - 3 = 3 ，经验变为：13 + 3 = 16 。<p>
 * - 你的精力与经验都超过第 3 个对手，所以获胜。<p>
 * 精力变为：3 - 2 = 1 ，经验变为：16 + 1 = 17 。<p>
 * 在比赛前进行了 8 小时训练，所以返回 8 。<p>
 * 可以证明不存在更小的答案。<p>
 * <p>
 * 示例 2：<p>
 * 输入：initialEnergy = 2, initialExperience = 4, energy = [1], experience = [3]<p>
 * 输出：0<p>
 * 解释：你不需要额外的精力和经验就可以赢得比赛，所以返回 0 。<p>
 * <p>
 * 提示：<p>
 * n == energy.length == experience.length<p>
 * 1 <= n <= 100<p>
 * 1 <= initialEnergy, initialExperience, energy[i], experience[i] <= 100<p>
 * <p>
 * 来源：力扣（LeetCode）<p>
 * 链接：<a href="https://leetcode.cn/problems/minimum-hours-of-training-to-win-a-competition">2383. 赢得比赛需要的最少训练时长</a><p>
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。<p>
 */
public class LeetCode2383 {

    @Test
    public void test01() {
//        int initialEnergy = 5, initialExperience = 3;
//        int[] energy = {1, 4, 3, 2}, experience = {2, 6, 3, 1};
//        int initialEnergy = 2, initialExperience = 4;
//        int[] energy = {1}, experience = {3};
        int initialEnergy = 1, initialExperience = 1;
        int[] energy = {1, 1, 1, 1}, experience = {1, 1, 1, 50};
        System.out.println(new Solution().minNumberOfHours(initialEnergy, initialExperience, energy, experience));
    }
}

class Solution {
    public int minNumberOfHours(int initialEnergy, int initialExperience, int[] energy, int[] experience) {
        // 需要锻炼的时间
        int ans = 0;
        int n = energy.length;
        for (int i = 0; i < n; i++) {
            if (initialEnergy <= energy[i]) {
                // 如果活力不足，则需要锻炼至 energy[i] + 1 的水平
                ans += energy[i] - initialEnergy + 1;
                // 进行比赛后变为 1
                initialEnergy = 1;
            } else {
                // 活力充足，进行比赛后减去对应的活力值
                initialEnergy -= energy[i];
            }
            if (initialExperience <= experience[i]) {
                // 经验值不足，则需要锻炼至 experience[i] + 1 的水平
                ans += experience[i] - initialExperience + 1;
                // 当前经验值变为 experience[i] + 1
                initialExperience = experience[i] + 1;
            }
            // 不管经验值是否充足，进行比赛之后都将对手的经验值加进来
            initialExperience += experience[i];
        }
        return ans;
    }
}
